package cn.com.zcode.core.control;

import java.io.IOException;
import java.io.Writer;
import java.util.HashSet;
import java.util.Set;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import cn.com.zcode.user.model.User;
import cn.com.zcode.user.service.UserService;
import cn.com.zcode.user.util.UserUtil;

public class AuthFilter implements Filter {
	private Logger logger = Logger.getLogger(AuthFilter.class);
	private String startPage;
	private Set<String> exclude = new HashSet<String>();
	private UserService userService ;
	private static final String KEY_STARTPAGE = "startPage";
	private static final String KEY_EXCLUDE = "exclude";

	
	@Override
	public void destroy() {

	}

	@Override
	public void doFilter(ServletRequest requ, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) requ;
		HttpServletResponse response = (HttpServletResponse) resp;
		HttpSession session = request.getSession();
		User user = (User) session.getAttribute(User.SESSION_USER);
		String url = request.getRequestURI();
		String ctx = request.getContextPath();
		url = url.substring(ctx.length());
		logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
		logger.debug("Auth Filter Check with Url->>[" + url + "]");

		if (user != null || startPage.equals(url) || exclude.contains(url)) {
			chain.doFilter(requ, resp);
		} else {
			User cookieUser = UserUtil.getUserFromCookie(request);
			if (cookieUser != null) {
				user = this.userService.getUser(cookieUser.getUsername(), cookieUser.getPassword(), false);
			}
			if (user != null) {
				this.userService.initUser(user,request,response, false);
				logger.info("Cookie 中取到用户："+user);
				chain.doFilter(requ, resp);
			} else if (isAjaxRequest(request)) {
				Writer writer = resp.getWriter();
				writer.write("nosession");
				writer.close();
				logger.debug("Ajax Request....response:nosession");
			} else {
				response.sendRedirect(ctx + startPage + response.encodeURL("?url=" + url));
				logger.debug(">>>>>>>Filter:" + url);

			}
		}
		logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");

	}

	private boolean isAjaxRequest(HttpServletRequest request) {
		String header = request.getHeader("X-Requested-With");
		if (header != null && "XMLHttpRequest".equals(header))
			return true;
		else
			return false;
	}

	@Override
	public void init(FilterConfig config) throws ServletException {
		this.startPage = config.getInitParameter(KEY_STARTPAGE);
		String excludeStr = config.getInitParameter(KEY_EXCLUDE);
		String[] excludeArr = excludeStr.split(",");
		ServletContext context = config.getServletContext();
		WebApplicationContext webcontext = WebApplicationContextUtils.getRequiredWebApplicationContext(context);
		this.userService = (UserService)webcontext.getBean("userService");
		for (String string : excludeArr) {
			if ((string.trim()).length() > 0) {
				exclude.add(string);
			}
		}
	}

}
